#include "ULUI_InputPad.h"
#include "UL_Global.h"
#include <SDL/sprig.h>

#define MAX_BUTTONS	12

struct buttonKeysymMap{
	SDLKey keysym;
	int buttonIndex;
	char c;
};

struct buttonKeysymMap b2kMap[] ={
	{SDLK_UNKNOWN, -1, '0'},
	{SDLK_1, 1, '1'},
	{SDLK_2, 2, '2'},
	{SDLK_3, 3, '3'},
	{SDLK_4, 4, '4'},
	{SDLK_5, 5, '5'},
	{SDLK_6, 6, '6'},
	{SDLK_7, 7, '7'},
	{SDLK_8, 8, '8'},
	{SDLK_9, 9, '9'},
	{SDLK_0, 10, '0'},
	{SDLK_MINUS, 11, '-'},
	{SDLK_KP1, 1, '1'},
	{SDLK_KP2, 2, '2'},
	{SDLK_KP3, 3, '3'},
	{SDLK_KP4, 4, '4'},
	{SDLK_KP5, 5, '5'},
	{SDLK_KP6, 6, '6'},
	{SDLK_KP7, 7, '7'},
	{SDLK_KP8, 8, '8'},
	{SDLK_KP9, 9, '9'},
	{SDLK_KP0, 10, '0'},
	{SDLK_KP_MINUS, 11, '-'},
	{SDLK_BACKSPACE, 12, '0'}, //Don't care the value
};

ULUI_InputPad::ULUI_InputPad():bgRGB(150, 150, 150), boarderRGB(20, 20, 20), solidBg(false)
{
	fontWidth = fontHeight = 0;
}

void ULUI_InputPad::SetFont(VSDL_Font *font)
{
	ULUI_Menu button;
	char buf[8];
	int i;

	if (font == NULL){
		return ;
	}

	button.SetFont(font);

	//Retrieve font width and height
	button.SetTitle(" 1  ");
	button.GetTitleSize(fontWidth, fontHeight);

	//Setup buttons for numbers(1 - 9, 0 is special)
	for (i = 1; i <= 9; i++){
		sprintf(buf, " %d  ", i);
		button.SetID(i);
		button.SetTitle(buf);
		buttons.AddMenu(button);		
	}

	//Setup buttons for '-', '0' and 'D'
	button.SetID(i++);
	button.SetTitle(" -  ");
	buttons.AddMenu(button);

	button.SetID(i++);
	button.SetTitle(" 0  ");
	buttons.AddMenu(button);

	button.SetID(i);
	button.SetTitle(" D  ");
	buttons.AddMenu(button);
}

void ULUI_InputPad::SetStartXY(VSDL_Point point)
{
	startXY = point;
}

void ULUI_InputPad::EnableSolidBg(bool enabled)
{
	solidBg = enabled;
}

void ULUI_InputPad::SetBgColor(VSDL_RGB rgb)
{
	bgRGB = rgb;
}

void ULUI_InputPad::SetBoarderRGB(VSDL_RGB rgb)
{
	boarderRGB = rgb;
}

void ULUI_InputPad::UpdateStatus(int mouseX, int mouseY)
{
	buttons.UpdateMenuList(mouseX, mouseY);	
}

void ULUI_InputPad::OnMouseDown(int mouseX, int mouseY)
{
	for (int i = 1; i <= MAX_BUTTONS; i++){
		ULUI_Menu &menu = buttons.GetMenu(i);

		if (menu.IsXYInRect(mouseX, mouseY)){
			PushKeysym(b2kMap[i].keysym);	
			break;
		}
	}
}

void ULUI_InputPad::PushKeysym(SDLKey keysym)
{
	char c = 0;
	//Special care for BACKSPACE key
	if (keysym == SDLK_BACKSPACE){
		PopKeysym();
		return ;
	}
	
	while (keysymList.size() >= MAX_STRING_SIZE){
		keysymList.pop_front();
	}

	for (int i = 1; i <= 22; i++){
		if (keysym == b2kMap[i].keysym){
			c = b2kMap[i].c;		
			break;
		}
	}

	if (c != 0){
		keysymList.push_back(c);
	}
}

void ULUI_InputPad::PopKeysym()
{
	if (keysymList.empty()){
		return ;
	}

	keysymList.pop_back();
}

void ULUI_InputPad::ClearString()
{
	keysymList.clear();
}

char *ULUI_InputPad::GetString()
{
	int i = 0;

	if (keysymList.empty()){
		return NULL;
	}

	for (iter = keysymList.begin(); iter != keysymList.end(); iter++){
		str[i++] = *iter;		
	}

	str[i] = '\0';

	return str;
}

void ULUI_InputPad::Reset()
{
	keysymList.clear();
	buttons.Reset();
}

void ULUI_InputPad::Show(SDL_Surface *destSurf)
{
	int count = 0;
	list<ULUI_Menu>::iterator iterMenu;
	VSDL_Point currentXY;

	if (destSurf == NULL){
		return ;
	}

	currentXY = startXY;

	for (iterMenu = buttons.menuList.begin(); iterMenu != buttons.menuList.end(); iterMenu++){
		//Draw rect
		if (solidBg){
			SPG_RectFilled(destSurf, currentXY.x, currentXY.y, currentXY.x + fontWidth, currentXY.y + fontHeight, bgRGB.GetRGB32(destSurf));
			SPG_Rect(destSurf, currentXY.x, currentXY.y, currentXY.x + fontWidth, currentXY.y + fontHeight, boarderRGB.GetRGB32(destSurf));
		}else{
			SPG_Rect(destSurf, currentXY.x, currentXY.y, currentXY.x + fontWidth, currentXY.y + fontHeight, boarderRGB.GetRGB32(destSurf));
		}

		(*iterMenu).Blit(destSurf, currentXY);
		
		count++;
		currentXY.x += fontWidth;

		if (count == 3){
			currentXY.x = startXY.x;
			currentXY.y += fontHeight;
			count = 0;	
		}	
	}
}
